import re

from django.contrib.auth import authenticate
from django.contrib.auth.models import update_last_login, User, Group
from rest_framework import serializers, status
from rest_framework.fields import SerializerMethodField
from rest_framework.serializers import ModelSerializer
from rest_framework_simplejwt.serializers import TokenObtainSerializer
from rest_framework_simplejwt.settings import api_settings
from rest_framework_simplejwt.tokens import RefreshToken

from users.models import UserDetail, Friend, FriendRequest

from utils.tools import myDESCipher


class RegisterCodeSerializer(serializers.Serializer):
    mobile = serializers.CharField(max_length=11, help_text="手机号码")

    def validate_mobile(self, mobile):
        validatemobile = re.compile(r'^1[3-9]\d{9}$')
        if validatemobile.match(mobile):
            return mobile
        raise serializers.ValidationError('手机号码格式不正确，请重新输入！')


class RegisterSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=30, label='账号名', help_text='账号名')
    password = serializers.CharField(min_length=6, label='密码', help_text='密码')
    mobile = serializers.CharField(max_length=11, label='手机号码', help_text='手机号码')
    code = serializers.CharField(max_length=4, label='验证码', help_text='验证码')
    email = serializers.EmailField(help_text='用户邮箱')

    def validate_mobile(self, mobile):
        validatemobile = re.compile(r'^1[3-9]\d{9}$')
        if validatemobile.match(mobile):
            return mobile
        raise serializers.ValidationError('手机号码格式不正确，请重新输入！')

    def validate_code(self, code):
        if code.isdigit():
            return code
        raise serializers.ValidationError('验证码格式不符合全数字规则,请重新输入！')

    def validate_password(self, password):
        if len(password) >= 6:
            return password
        raise serializers.ValidationError('l密码不能小于6位数,请重新输入！')


class LoginTokenObtainSerializer(TokenObtainSerializer):
    token_class = RefreshToken

    def validate(self, attrs):
        data = {}
        print(attrs['password'])
        # 对于密码进行解密。再做校验
        attrs['password'] = myDESCipher.decrypt_password(attrs['password'])
        # 校验用户是否存在 (校验用户是否是活跃状态，是否是激活)
        user = authenticate(username=attrs['username'], password=attrs['password'])
        # 生成token
        if user:
            refresh = self.get_token(user)
            data["access"] = str(refresh.access_token)
            data['user'] = user

        if api_settings.UPDATE_LAST_LOGIN:
            update_last_login(None, user)
        return data


class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"


class WirterUserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=40, help_text='用户名')
    position = serializers.CharField(max_length=40, help_text='职位')
    age = serializers.IntegerField(help_text='年龄')
    sex = serializers.IntegerField(help_text='性别')
    mobile = serializers.CharField(max_length=11, help_text='手机号码')
    email = serializers.EmailField(help_text='QQ邮箱')
    address = serializers.CharField(max_length=100, help_text='联系地址')

    def validate(self, instance):
        data = {}
        validatemobile = re.compile(r'^1[3-9]\d{9}$')
        if not validatemobile.match(instance['mobile']):
            data = {
                'status': status.HTTP_400_BAD_REQUEST,
                "msg": '手机号码格式不正确，请重新输入！'
            }

        user = User.objects.using("salves").filter(userdetail__mobile=instance['mobile']).first()
        if user:
            data = {
                'status': status.HTTP_400_BAD_REQUEST,
                "msg": '该手机号码已存在于系统当中！'
            }

        user = User.objects.using("salves").filter(username=instance['username']).first()
        if user:
            data = {
                'status': status.HTTP_400_BAD_REQUEST,
                "msg": '该用户姓名已存在于系统当中！'
            }

        user = User.objects.using("salves").filter(email=instance['email']).first()
        if user:
            data = {
                'status': status.HTTP_400_BAD_REQUEST,
                "msg": '该邮箱已存在于系统当中！'
            }
        return data


class GroupSerializer(ModelSerializer):
    class Meta:
        model = Group
        fields = ['id', 'name']


class UserDetailSerializer(ModelSerializer):
    class Meta:
        model = UserDetail
        exclude = ['update_time', 'is_delete', 'user', 'id', 'create_time']


class NotActiveStudentSerializer(ModelSerializer):
    mobile = SerializerMethodField()

    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'date_joined', 'mobile']

    def get_mobile(self, instance):
        return instance.userdetail.mobile


class UserInfoSerializer(ModelSerializer):
    id = SerializerMethodField()
    userdetail = UserDetailSerializer(required=False, read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'is_active', 'email', 'date_joined', 'userdetail']

    def get_id(self, instance):
        return myDESCipher.encryption(str(instance.id))


class UpdateUserPasswordSerializer(serializers.Serializer):
    old_password = serializers.CharField(help_text='旧密码', max_length=100)
    new_password = serializers.CharField(help_text='新密码', max_length=100)

    def validate_old_password(self, password):
        if len(password) < 6:
            raise serializers.ValidationError('旧密码不能小于6位数')
        return password

    def validate_new_password(self, password):
        if len(password) < 6:
            raise serializers.ValidationError('新密码不能小于6位数')
        return password


class UpdateUserDetailSerializer(serializers.Serializer):
    email = serializers.EmailField(help_text='用户邮箱')
    mobile = serializers.CharField(max_length=11, help_text='手机号码')
    age = serializers.IntegerField(help_text='年龄')
    sex = serializers.IntegerField(help_text='性别')
    birthday = serializers.DateField(help_text='生日')
    address = serializers.CharField(max_length=100, help_text='联系地址')
    synopsis = serializers.CharField(help_text='简介', max_length=200)


class ActiveStudentSerializer(serializers.Serializer):
    user_id = serializers.CharField(max_length=20, help_text="用户ID")


class FriendRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = FriendRequest
        fields = ['receiver']


class IsFriendSerializer(serializers.Serializer):
    is_friend = serializers.BooleanField()


class UserDetailAvatarSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(source='user.first_name', read_only=True)

    class Meta:
        model = UserDetail
        fields = ['avatar', 'first_name']


class FriendSerializer(serializers.ModelSerializer):
    friend_username = serializers.CharField(source='friend.username', read_only=True)
    user_details = UserDetailAvatarSerializer(source='friend.userdetail', read_only=True)

    class Meta:
        model = Friend
        fields = ['friend', 'friend_username', 'user_details']


class ShowFriendRequest(serializers.ModelSerializer):
    requester_username = serializers.CharField(source='requester.username', read_only=True)
    user_details = UserDetailAvatarSerializer(source='requester.userdetail', read_only=True)

    class Meta:
        model = FriendRequest
        fields = ['requester', 'requester_username', 'status', 'user_details']


class UserIDDetailSerializer(serializers.ModelSerializer):
    sex = serializers.SerializerMethodField()

    class Meta:
        model = UserDetail
        fields = ['mobile', 'age', 'sex', 'birthday', 'address', 'synopsis']

    def get_sex(self, obj):
        return dict(UserDetail.SEX_CHOICES).get(obj.sex)
